package com.ruoyi.controller;


import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.constants.Constant;
import com.ruoyi.dto.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Api(tags = "预测预警分级模型算法")
@RequestMapping("/riskEvaluateWeb")
@RestController
public class RiskEvaluate2WebController {

    @ApiOperation("13燃气管道泄漏扩散分析模型-Leakage and diffusion of gas pipeline")
    @PostMapping("/ladogp")
    public Map ladogp(@RequestBody LadogpDto ladogpDto) {
        Map map = new HashMap();
        if(ladogpDto.getC()==1)
        {
            map.put("r",Constant.DoubleFormat(Math.pow((ladogpDto.getT()/13.12),(1/2.22))));
        }
        else if(ladogpDto.getC()==2)
        {
            map.put("r",(Constant.DoubleFormat(-1.305*Math.exp((-ladogpDto.getT()/1589.93))+1.6315)));
        }
        else {
            map.put("msg","请输入正确的燃气土壤浓度，1代表1%;2代表5%");
        }
        return map;
    }



    @ApiOperation("14燃气管道泄漏爆炸危害模型-gas pipeline leakage and explosion")
    @PostMapping("/gplae")
    public Map gplae(@RequestBody GplaeDto gplaeDto) {
        Double Wf = 0.0;  // (kg )
        Double WTNT = 0.0;  // (kg )
        Double R1 = 0.0;  // 死亡半径(m)
        Double R2 = 0.0;  // 重伤半径(m)
        Double R3 = 0.0;  // 轻伤半径(m)
        Double R4 = 0.0;  // 建筑物破坏半径(m)
        Double pow1_3 = 0.333333;
        Double pow1_6 = 0.166666;
        Map map = new HashMap();

        // 长方体
        if(gplaeDto.getShape()==1)
        {
            Wf = Constant.DoubleFormat(gplaeDto.getHigh()*gplaeDto.getWide()*gplaeDto.getLength()*0.1*16/22.4);
        }
        else if(gplaeDto.getShape()==2) // 圆柱体
        {
            Wf = Constant.DoubleFormat(Constant.PI*gplaeDto.getR()*gplaeDto.getR()*gplaeDto.getLength()*0.1*16/22.4);
        }
        else if(gplaeDto.getShape()==3) // 不规则
        {
            Wf =  Constant.DoubleFormat(gplaeDto.getV()*0.1*16/22.4);
        }
        WTNT = Constant.DoubleFormat(Constant.LAMDA*Wf*Constant.DELTA_HCF/Constant.DELTA_HTNT);
        map.put("WTNT",WTNT);
//        R1 = Constant.DoubleFormat(13.6*Math.pow(WTNT/1000,0.3));
        R1 = Constant.DoubleFormat(13.6/8*Math.pow(WTNT/1000,0.3));
        map.put("R1",R1);

        Double E = WTNT*Constant.DELTA_HTNT;
        R2 = Constant.DoubleFormat(Constant.ZR2*Math.pow((E/Constant.P0),(pow1_3)));
        map.put("R2",R2);

        R3 = Constant.DoubleFormat(Constant.ZR3*Math.pow((E/Constant.P0),(pow1_3)));
        map.put("R3",R3);

        Double tmp = 1+ Math.pow(((double) 3175/WTNT),2);
        Double tmp1 = Math.pow(tmp,(pow1_6));
        R4 = Constant.DoubleFormat(Constant.KI_R4*Math.pow(WTNT,(pow1_3))/tmp1);
        map.put("R4",R4);

        return map;
    }


    @ApiOperation("15液化气充装站泄漏爆炸危害模型")
    @PostMapping("/lpglae")
    public Map riskAccess(@RequestBody Lpg lpg) throws UnknownHostException {
        Map map = new HashMap();

        //液化气泄露前液体温度,单位为K
        Double T = 298.0;

        //液化气沸点
        Double T0 = 231.15;

        /*
         *输入LPG站储槽的尺寸信息直径d、长度L、放置方向（横、竖）
         * 计算液面面积Ar
         */
        Double Ar = 0.0;
        Double r = lpg.getD()/(double)2;
        // "0"为横放，“1”为竖放
        if(lpg.getDirection().equals("1"))
        {
            Ar = Constant.DoubleFormat(Constant.PI*r*r);
        }
        else{
            if(lpg.getD()<lpg.getH())
            {
                System.out.println("液面高度太高！");
                Ar = Constant.DoubleFormat(Math.sqrt((lpg.getH() - lpg.getD())*lpg.getH())*2*lpg.getL());
            }
            else  // 推导出来了 （（d-H）*H）的开根号*2*L
            {
                Ar = Constant.DoubleFormat(Math.sqrt((lpg.getD()-lpg.getH())*lpg.getH())*2*lpg.getL());
            }

        }
        map.put("Ar",Ar);
        Double W0Part1 = 0.0;
        W0Part1 = Constant.DoubleFormat(Constant.LNG_C_d*lpg.getAh()*lpg.getDensity()*lpg.getT());

        Double W0Part2 = 0.0;
        Double tmp1 = Constant.DoubleFormat(2*(lpg.getP()-Constant.P0)/lpg.getDensity()+2*Constant.G*lpg.getGh());
        if(tmp1>=0.0){
            W0Part2 = Constant.DoubleFormat(Math.sqrt(tmp1));
        }
        else
        {
            System.out.println("LNG的W0出现负数，开不了根号！");
        }

        Double W0Part3 = 0.0;
        W0Part3 = Constant.DoubleFormat(lpg.getDensity()*Constant.G*Constant.LNG_C_d*Constant.LNG_C_d*lpg.getAh()*lpg.getAh()*lpg.getT()*lpg.getT()/Ar);

        Double W0 = 0.0;
        W0 = Constant.DoubleFormat(W0Part1*W0Part2*W0Part3);
        map.put("W0",W0);

        Double W = Constant.DoubleFormat(Constant.LPG_C_P*(T-T0)*W0/Constant.LPG_H);

        Double WTNT = Constant.DoubleFormat(1.8*Constant.LPG_A_E*Constant.LPG_H_F*W/Constant.LPG_H_TNT);
        map.put("WTNT",WTNT);

        Double deltaP = 1.0;
        deltaP = lpg.getP()-Constant.P0;
        if (deltaP<1.0)
            deltaP = 1.0;
        Double x = 0.0;
        Double x1 = 0.0;
        Double lnDeltaP = Constant.DoubleFormat(Math.log(deltaP));
        x1 = Constant.DoubleFormat(5.0502-0.8778*lnDeltaP+0.0398*lnDeltaP*lnDeltaP);
        x = Constant.DoubleFormat(0.3967*Math.pow(WTNT,0.333333)*Math.exp(x1));
        map.put("x",x);

        return map;
    }

    @ApiOperation("16燃气管道开挖泄漏危害模型-gas pipeline excavation")
    @PostMapping("/gpe")
    public Map gpe(@RequestBody LngCut lngCut) throws UnknownHostException {

        Map map = new HashMap();
        Double m =16.0;
        Double A = (Constant.DoubleFormat(Constant.PI*Math.pow(lngCut.getD()/2.0,2)));
        //液化气泄露前液体温度,单位为K
        Double L = 0.0;

        Double L1 = Constant.DoubleFormat((5.3* lngCut.getD())/Constant.LNG_CUT_C_T);
        Double L2 = Constant.DoubleFormat(Constant.LNG_CUT_T_F/(Constant.LNG_CUT_T_N*Constant.LNG_CUT_ALPHA));
        Double L3 = Constant.DoubleFormat(Constant.LNG_CUT_C_T+(1-Constant.LNG_CUT_C_T)*Constant.LNG_CUT_M_S/Constant.LNG_CUT_M_A);
        L = Constant.DoubleFormat(L1*Math.pow((L2*L3),(1.0/2)));
        map.put("L",L);

        List<Double> DsList = new ArrayList<>();

        //流出系数 Ds
        Double Ds1 = 0.0;
        Double Ds2 = 0.0;
        Ds1 = Constant.DoubleFormat(Math.pow((2*Constant.LNG_CUT_C_i*Constant.LNG_CUT_C_i*Constant.LNG_CUT_C_c*Constant.LNG_CUT_C_c)/(2*Constant.LNG_CUT_C_i*Constant.LNG_CUT_C_i-Constant.LNG_CUT_C_c*Constant.LNG_CUT_C_c),1.0/2));
        if(L > 0.1)
        {
            Double lTemp = 0.0;
            for (int i=1;i<10*L;i++)
            {
                lTemp = lTemp +0.1;
                if(lTemp>L){
                    break;
                }
                Double Ds = 0.0;
                System.out.println("L:"+lTemp+"，i:"+i);
                Ds2 = Constant.DoubleFormat(Math.pow(Math.log(L/lTemp),(1.0/2)));
                Ds = Constant.DoubleFormat(Ds1*Ds2);
                DsList.add(Ds);
            }
        }

        map.put("Ds",DsList);

        //γ =cp/cv
        //流出系数 Y
        Double Y = 0.0;

        Double Y1 = 0.0;
        Y1 = Constant.DoubleFormat(Constant.P0/ lngCut.getP());

        Double Y2 = 0.0;
        Double r1 = Constant.DoubleFormat(1/Constant.LNG_CUT_γ);
        Y2 = Constant.DoubleFormat(1 - Constant.DoubleFormat(Math.pow(Y1,Constant.LNG_CUT_γ-r1)));

        Double Y3 = 0.0;
        Y3 = Constant.DoubleFormat((2/ Constant.LNG_CUT_γ - 1))* Math.pow(((Constant.LNG_CUT_γ+1)/2),(Constant.LNG_CUT_γ+r1-1));

        Double y1111 = Math.pow(Y2,0.5);

        Y = Constant.DoubleFormat(Math.pow(Y1,r1)* Math.pow(Y2,0.5)* Y3);
        map.put("Y",Y);

        //可燃气体泄露质量流率 kg/s
        Double Q = 0.0;
        Double Q1 = 0.0;
        Q1 = Constant.DoubleFormat(Math.sqrt(((m*Constant.LNG_CUT_γ)/(Constant.LNG_CUT_R_g* lngCut.getT()))*Math.pow(2/(Constant.LNG_CUT_γ+1),((Constant.LNG_CUT_γ+1)/(Constant.LNG_CUT_γ-1)))));
        Q = Constant.DoubleFormat(Y*Constant.LNG_CUT_C_d* A* lngCut.getP()*Q1);
        map.put("Q",Q);


        List<Double> pdi = new ArrayList<Double>();
        if(L > 0.1)
        {
            Double lTemp = 0.0;
            for (int i=1;i<10*L;i++)
            {
                lTemp = lTemp+0.1;
                pdi.add(Constant.DoubleFormat(16.16+ 3.41*Math.log(Q/(lTemp*lTemp))));
                map.put("pdi",pdi);
            }
        }

        //燃料总质量
        Double Wf = 0.0;
        Wf = Constant.DoubleFormat(Q * lngCut.getTime());
        map.put("Wf",Wf);


        // A 蒸汽云的当量系数0.02%~14.9%，取中间值10%
        Double WTNT = 0.0;
        WTNT = Constant.DoubleFormat(0.1*Wf*Constant.LNG_CUT_Q_f/Constant.LNG_CUT_Q_TNT);
        map.put("WTNT",WTNT);

        //死亡半径
        Double R05 = 0.0;
        R05 = Constant.DoubleFormat(13.6*Math.pow((WTNT/1000),0.37));
        Double E = Constant.DoubleFormat(WTNT*Constant.LNG_CUT_E_TNT/Constant.P0);
        //重伤半径
        Double Rd05 = 0.0;
        Rd05 = Constant.DoubleFormat(Constant.LNG_CUT_ZRd05*Math.pow(E,0.3333));

        //轻伤半径
        Double Rd001 = 0.0;
        Rd001 = Constant.DoubleFormat(Constant.LNG_CUT_ZRd001*Math.pow(E,0.3333));
        map.put("R05",R05);
        map.put("Rd05",Rd05);
        map.put("Rd001",Rd001);

        return map;
    }

    @ApiOperation("17 传感器效能评估模型--1:传感器效能好,2:传感器效能差")
    @PostMapping("/sensorEvaluate")
    public AjaxResult sensorEvaluate(@RequestBody SensorEvaluateDto sensorEvaluateDto) {
        Map map = new HashMap();
        map.put("number",sensorEvaluateDto.getNumber());
        String lxyxsj = sensorEvaluateDto.getLxyxsj();
        String fssjjb = sensorEvaluateDto.getFssjjb();
        if("1".equals(lxyxsj) && "2".equals(fssjjb)){
            map.put("code","2");
            map.put("name","传感器效能差");
        }else{
            map.put("code","1");
            map.put("name","传感器效能好");
        }
        return AjaxResult.success(map);
    }

    @ApiOperation("18供水管道爆管定位模型")
    @PostMapping("/waterTubeBurstPosition")
    public AjaxResult waterTubeBurstPosition(@RequestBody WaterTubeBurstPositionDto waterTubeBurstPositionDto) {
        Map map = new HashMap();
        map.put("number",waterTubeBurstPositionDto.getNumber());
        BigDecimal jcdll = new BigDecimal(waterTubeBurstPositionDto.getJcdll());
        BigDecimal zbll = new BigDecimal(waterTubeBurstPositionDto.getZbll());
        int change = zbll.compareTo(jcdll);
        if("1".equals(waterTubeBurstPositionDto.getSxygx())){
            if(change>0){
                map.put("code","1");
                map.put("name","泄漏点可能在这两者之间也可能在压力计下游");
            }else if(change==0){
                map.put("code","0");
                map.put("name","不分析，转人工判断");
            }else if(change<0){
                map.put("code","2");
                map.put("name","爆管点在流量计上游");
            }
        }else if("0".equals(waterTubeBurstPositionDto.getSxygx())){
            if(change>0){
                map.put("code","3");
                map.put("name","爆管点在流量计下游");
            }else if(change==0){
                map.put("code","0");
                map.put("name","不分析，转人工判断");
            }else if(change<0){
                map.put("code","4");
                map.put("name","爆管点在这两者之间，也可能在压力计上游");
            }
        }
        return AjaxResult.success(map);
    }

    @ApiOperation("19供水爆管影响范围模型")
    @PostMapping("/waterTubeBurstAffect")
    public AjaxResult waterTubeBurstAffect(@RequestBody WaterTubeBurstAffectDto waterTubeBurstAffectDto) {
        Map map = new HashMap();
        map.put("number",waterTubeBurstAffectDto.getNumber());
        BigDecimal jcdqst = new BigDecimal(waterTubeBurstAffectDto.getJcdqst());
        BigDecimal jcddqz = new BigDecimal(waterTubeBurstAffectDto.getJcddqz());
        BigDecimal change = jcdqst.subtract(jcddqz).abs().divide(jcddqz);
        int start = change.compareTo(new BigDecimal(0.5));
        int end = change.compareTo(new BigDecimal(0.3));
        if(start==1){
            map.put("code","1");
            map.put("name","红色");
        }else if(end==-1){
            map.put("code","2");
            map.put("name","黄色");
        }else{
            map.put("code","3");
            map.put("name","橙色");
        }
        return AjaxResult.success(map);
    }


    @ApiOperation("21热力管道爆管危害分析-thermal pipeline explosion，Qo：液体泄漏速度；r：液池半径")
    @PostMapping("/tpe")
    public Map tpe(@RequestBody ThermalPipelineDto thermalPipelineDto) {
        Map map = new HashMap();

        Double Qo = 0.0;
            Double Qo2 = 0.0;
            Qo2=Constant.DoubleFormat(Math.sqrt(2*(thermalPipelineDto.getP()-Constant.P0)/thermalPipelineDto.getDensity()+2*Constant.G*thermalPipelineDto.getH()));
            Qo = Constant.DoubleFormat(Constant.CHEMICAL_C_d*thermalPipelineDto.getA()*thermalPipelineDto.getDensity()*Qo2);
            Double r = 0.0; //夜池半径
            r = Constant.DoubleFormat(Math.pow(32*Constant.G*Qo*thermalPipelineDto.getTime()*thermalPipelineDto.getTime()*thermalPipelineDto.getTime()*thermalPipelineDto.getTime()/(Constant.PI*thermalPipelineDto.getDensity()),1.0/4.0));

            map.put("Qo",Qo);
            map.put("r",r);

        return map;
    }

    @ApiOperation("22电梯运行故障预警分析模型-Elevator operation alarm")
    @PostMapping("/elevatorof")
    public Map elevatorof(@RequestBody ElevatorAlarmDto elevatorAlarmDto) {
        Map map = new HashMap();

        if(elevatorAlarmDto.getXList()!=null && elevatorAlarmDto.getXList().size()>1){
            Double xTotal = 0.0;
            for (Double x:elevatorAlarmDto.getXList()) {
                xTotal += x;
            }
            if(Math.sqrt(xTotal/(elevatorAlarmDto.getXList().size()-1))>0.0141)
            {
                map.put("alarm","YES");
                map.put("X","YES");
                return map;
            }
        }

        if(elevatorAlarmDto.getYList()!=null && elevatorAlarmDto.getYList().size()>1){
            Double yTotal = 0.0;
            for (Double y:elevatorAlarmDto.getYList()) {
                yTotal += y;
            }
            if(Math.sqrt(yTotal/(elevatorAlarmDto.getYList().size()-1))>0.0089)
            {
                map.put("alarm","YES");
                map.put("Y","YES");
                return map;
            }
        }

        if(elevatorAlarmDto.getZList()!=null && elevatorAlarmDto.getZList().size()>1){
            Double zTotal = 0.0;
            for (Double z:elevatorAlarmDto.getZList()) {
                zTotal += z;
            }
            if(Math.sqrt(zTotal/(elevatorAlarmDto.getZList().size()-1))>0.00168)
            {
                map.put("alarm","YES");
                map.put("Z","YES");
                return map;
            }
        }

        map.put("alarm","NO");
        return map;
    }

    @ApiOperation("23危化品泄漏扩散预警分析模型-dangerous chemicals leakage and diffusion；Qo：液体泄漏速度；r：液池半径")
    @PostMapping("/dclad")
    public Map dclad(@RequestBody ChemicalsLeakageDto chemicalsLeakageDto) {
        Map map = new HashMap();

        Double Qo = 0.0;
        //液体
        if(chemicalsLeakageDto.getType()!=null&&chemicalsLeakageDto.getType().equals("1")){
            Double Qo2 = 0.0;
            Qo2=Constant.DoubleFormat(Math.sqrt(2*(chemicalsLeakageDto.getP()-Constant.P0)/chemicalsLeakageDto.getDensity()+2*Constant.G*chemicalsLeakageDto.getH()));
            Qo = Constant.DoubleFormat(Constant.CHEMICAL_C_d*chemicalsLeakageDto.getA()*chemicalsLeakageDto.getDensity()*Qo2);
            Double r = 0.0; //夜池半径
            r = Constant.DoubleFormat(Math.pow(32*Constant.G*Qo*chemicalsLeakageDto.getTime()*chemicalsLeakageDto.getTime()*chemicalsLeakageDto.getTime()*chemicalsLeakageDto.getTime()/(Constant.PI*chemicalsLeakageDto.getDensity()),1.0/4.0));

            map.put("Qo",Qo);
            map.put("r",r);
            map.put("type","液体");
        }
        //气体
        else if(chemicalsLeakageDto.getType()!=null&&chemicalsLeakageDto.getType().equals("2")){
         //Y为气体的膨胀因子
            Double Y = 0.0;
            Double Qo2 = 0.0;
            Double Y2 = 0.0;
            Double k = (Double) gasK(chemicalsLeakageDto.getGasName()).get("k");
            Double m = (Double) gasK(chemicalsLeakageDto.getGasName()).get("m");
            Qo2 = Constant.DoubleFormat(Math.sqrt((m*k)/(Constant.LNG_CUT_R_g*chemicalsLeakageDto.getT())*Math.pow(2.0/(k+1),(k+1)/(k-1))));
            Y = Constant.DoubleFormat(1.0/(k-1)*Math.pow((k+1)/2.0,(k+1)/(k-1))*Math.pow(chemicalsLeakageDto.getP()/Constant.P0,2.0/k)*(1-Math.pow(Constant.P0/chemicalsLeakageDto.getP(),(k-1)/k)));
            Qo = Constant.DoubleFormat(Y*Constant.CHEMICAL_GAS_C_d*chemicalsLeakageDto.getA()*chemicalsLeakageDto.getP()*Qo2);
            map.put("Y",Y);
            map.put("Qo",Qo);
            map.put("type","气体");

            List<Double> cList = new ArrayList<>();
            Double sigma = 0.00005;

            for(int i = 1; i<11; i++)
            {
                Double c = 0.0;
                c = 2*Qo/(Math.pow(2*Constant.PI,3.0/2.0)*sigma*sigma*sigma)*Math.pow(Math.exp(-(i*10)*(i*10)/(2.0*sigma*sigma)),2);
               cList.add(c);
            }
            map.put("cList",cList);
        }


        map.put("alarm","NO");
        return map;
    }


    /**
     * 气体的绝热指数
     */
    public Map gasK(String gas)
    {
        Map map = new HashMap();

        if(gas.equals("H2"))
        {
           map.put("k",1.41);
           map.put("m",2.0);
        }
        else if(gas.equals("N2"))
        {
            map.put("k",1.402);
            map.put("m",28.0);
        }
        else if(gas.equals("O2"))
        {
            map.put("k",1.397);
            map.put("m",32.0);
        }
        else if(gas.equals("SO2"))
        {
            map.put("k",1.272);
            map.put("m",64.0);
        }
        else if(gas.equals("NH3"))
        {
            map.put("k",1.313);
            map.put("m",17.0);
        }
        else if(gas.equals("C2H2"))
        {
            map.put("k",1.235);
            map.put("m",26.0);
        }
        else if(gas.equals("C3H4"))
        {
            map.put("k",1.249);
            map.put("m",38.0);
         }
        else if(gas.equals("CH4"))
        {
            map.put("k",1.4);
            map.put("m",16.0);
        }
        else {
            map.put("k",1.4);
            map.put("m",16.0);
        }
        return map;
    }


    public static void main(String[] args) {
        Double sigma = 0.00005;
        System.out.printf(String.valueOf(Math.exp(-100)*Math.pow(Math.exp(2),100)));

       /* for(int i = 0; i<100; i++) {
            System.out.println(2 * 420000000 / (Math.pow(2 * Constant.PI, 3.0 / 2.0) ) * 20000* Math.exp(-(i * 1) *(i * 1) / (2.0 * sigma * sigma))* 20000* Math.exp(-(i * 1) *(i * 1) / (2.0 * sigma * sigma))*20000);
        }
        System.out.printf("%.4f ",(187*1.95550784*1.95550784*1.95550784-(269*1.95550784*1.95550784)-(119*1.95550784)-137));
        System.out.printf("%.4f ",(13.6*Math.pow(17.86/1000,0.3)));
        System.out.printf("%.4f ",(1.9555*Math.pow(17.86*4520/Constant.P0,0.3333333333)));
        System.out.println(Math.exp(1));*/
    }
}
